package com.zx.idc.backend.gui.api.management.basicdata.report;


import com.zx.idc.ds.base.cus.entity.BaseCustomer;
import com.zx.idc.ds.base.house.entity.*;
import com.zx.idc.ds.base.ip.entity.BaseIpAddressInfo;
import com.zx.idc.ds.base.serve.entity.BaseServiceDomain;
import com.zx.idc.xml.entity.basedata.basic.HouseInfo;
import com.zx.idc.xml.entity.basedata.basic.UserInfo;
import com.zx.idc.xml.entity.basedata.basic.houseinfo.FrameInfo;
import com.zx.idc.xml.entity.basedata.basic.houseinfo.GatewayInfo;
import com.zx.idc.xml.entity.basedata.basic.houseinfo.HouseOfficer;
import com.zx.idc.xml.entity.basedata.basic.houseinfo.IpSegInfo;
import com.zx.idc.xml.entity.basedata.basic.userinfo.*;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author rxliuli
 */
@Component
public class IdcBasicDataUtil {
    private static final Integer USER_TYPE_INTERNET = 1;
    private final Logger log = LoggerFactory.getLogger(getClass());

    public static IpSegInfo getIpSegInfo(BaseIpAddressInfo biai) {
        return new IpSegInfo(biai.getId(), biai.getStartIp(), biai.getEndIp(), biai.getUseType(), biai.getUseCompany(), biai.getIdType(), biai.getIdNumber(), biai.getSourceCompany(), biai.getAssignCompany(), biai.getAssignUseTime());
    }

    public static HouseInfo convertHouseInfo(BaseHouseInfo baseHouseInfo, BaseHouseOfficer baseHouseOfficer, List<BaseHouseLinkInfo> baseHouseLinkInfoList, List<BaseIpAddressInfo> baseIpAddressInfoList, List<BaseFrameInfo> baseFrameInfoList) {
        return new HouseInfo(baseHouseInfo.getId(), baseHouseInfo.getHouseName(), baseHouseInfo.getHouseType(), baseHouseInfo.getHouseProvince(), baseHouseInfo.getHouseCity(), baseHouseInfo.getHouseCounty(), baseHouseInfo.getHouseAddress(), baseHouseInfo.getZipCode(),
            //每个机房的安全责任人
            Optional.ofNullable(baseHouseOfficer)
                .map(bho -> new HouseOfficer(bho.getName(), bho.getIdType(), bho.getId().toString(), bho.getTel(), bho.getMobile(), bho.getEmail()))
                .orElse(null),
            baseHouseLinkInfoList.stream()
                .map(bhli -> new GatewayInfo(bhli.getId(), bhli.getBandWidth(), bhli.getGatewayIp(), bhli.getLinkType(), bhli.getAccessUnit()))
                .collect(Collectors.toList()),
            baseIpAddressInfoList.stream()
                .map(IdcBasicDataUtil::getIpSegInfo)
                .collect(Collectors.toList()),
            baseFrameInfoList.stream()
                .map(bfi -> new FrameInfo(bfi.getId(), bfi.getUseType(), bfi.getDistribution(), bfi.getOccupancy(), bfi.getFrameName()))
                .collect(Collectors.toList()));
    }

    /**
     * 获取服务信息列表
     *
     * @param baseHouseInfoList     基础服务信息列表
     *                              信息
     * @param baseHouseLinkInfoList IDC /ISP
     */
    public List<HouseInfo> getHouseInfoList(List<BaseHouseInfo> baseHouseInfoList, Map<Long, BaseHouseOfficer> baseHouseOfficerMap, List<BaseHouseLinkInfo> baseHouseLinkInfoList, List<BaseIpAddressInfo> baseIpAddressInfoList, List<BaseFrameInfo> baseFrameInfoList) {
        return baseHouseInfoList.stream()
            .map(baseHouseInfo -> convertHouseInfo(baseHouseInfo, baseHouseOfficerMap.getOrDefault(baseHouseInfo.getHouseOfficer(), null), baseHouseLinkInfoList, baseIpAddressInfoList, baseFrameInfoList))
            .collect(Collectors.toList());
    }

    /**
     * 获取用户信息列表
     */
    public List<UserInfo> getUserInfoList(List<BaseIdcHouseArea> baseIdcHouseAreaList, List<BaseFrameInfo> baseFrameInfoList, List<BaseCustomer> baseCustomerList, Map<Long, BaseHouseOfficer> baseCustomerHouseOfficerMap, List<BaseServiceInfo> baseServiceInfoList, Map<Long, List<BaseServiceDomain>> baseServiceDomainMap, List<BaseHousesHoldInfo> baseHousesHoldInfoList, List<BaseIpTransInfo> baseIpTransInfoList) {
        return baseCustomerList.stream()
            .map(bc -> {
                final List<ServiceInfo> serviceInfo = baseServiceInfoList.stream()
                    .filter(bsi -> bsi.getCustomerId().equals(bc.getId()))
                    .map(bsi -> {
                        final List<Integer> serviceContentlist = Arrays.stream(bsi.getServiceContent().split(","))
                            .filter(StringUtils::isNotEmpty)
                            .map(s -> Integer.parseInt(s.trim()))
                            .collect(Collectors.toList());
                        final List<HousesHoldInfo> housesHoldInfoList = baseHousesHoldInfoList.stream()
                            .filter(bhhi -> bhhi.getCustomerId().equals(bc.getId()))
                            .map(bhhi -> {
                                final List<IpTrans> ipTransList = baseIpTransInfoList.stream()
                                    .filter(biti -> biti.getHoldId().equals(bhhi.getId()))
                                    .map(biti -> {
                                        NetIp netIp = null;
                                        if (StringUtils.isNotEmpty(biti.getPrivateStartIp()) || StringUtils.isNotEmpty(biti.getPrivateEndIp())) {
                                            netIp = new NetIp(biti.getPrivateStartIp(), biti.getPrivateEndIp());
                                        }
                                        return new IpTrans(new InternetIp(biti.getInternetStartIp(), biti.getInternetEndIp()), netIp);
                                    })
                                    .collect(Collectors.toList());
                                VirtualServer virtualServer = null;
                                if (StringUtils.isNotEmpty(bhhi.getVirtualHostName())) {
                                    virtualServer = new VirtualServer(
                                        bhhi.getVirtualHostName(),
                                        bhhi.getVirtualHostState(),
                                        bhhi.getVirtualHostType(),
                                        bhhi.getVirtualHostAddress(),
                                        bhhi.getVirtualHostManagement()
                                    );
                                }
                                return new HousesHoldInfo(
                                    bhhi.getId(),
                                    getHouseIdByBaseHousesHoldInfo(baseIdcHouseAreaList, baseFrameInfoList, bhhi),
                                    bhhi.getDistributeTime(),
                                    bhhi.getBandWidth(),
                                    ipTransList,
                                    bhhi.getFrameInfoId(),
                                    virtualServer
                                );
                            })
                            .collect(Collectors.toList());
                        return new ServiceInfo(bsi.getId(),
                            serviceContentlist,
                            bsi.getRegType(),
                            bsi.getRegId(),
                            bsi.getSetMode(),
                            bsi.getBusinessType(),
                            baseServiceDomainMap.getOrDefault(bsi.getId(), Collections.emptyList()).stream()
                                .map(bsd -> new Domain(bsd.getId(), bsd.getDomain()))
                                .collect(Collectors.toList()),
                            housesHoldInfoList
                        );
                    })
                    .collect(Collectors.toList());
                final List<HouseHoldInfo> houseHoldInfoList = baseHousesHoldInfoList.stream()
                    .filter(bhhi -> bhhi.getCustomerId().equals(bc.getId()))
                    .map(bhhi -> new HouseHoldInfo(
                        bhhi.getId(),
                        getHouseIdByBaseHousesHoldInfo(baseIdcHouseAreaList, baseFrameInfoList, bhhi),
                        bhhi.getBandWidth(),
                        bhhi.getDistributeTime(),
                        baseIpTransInfoList.stream()
                            .filter(biti -> biti.getHoldId().equals(bhhi.getId()))
                            .map(biti -> new IpSeg(biti.getId(), biti.getInternetStartIp(), biti.getInternetEndIp()))
                            .collect(Collectors.toList())
                    ))
                    .collect(Collectors.toList());
                UserInfo userInfo = new UserInfo(
                    bc.getId(),
                    bc.getUserType(),
                    new Info(
                        bc.getUnitName(),
                        bc.getUnitNature(),
                        bc.getIdType(),
                        bc.getIdNumber(),
                        Optional.ofNullable(baseCustomerHouseOfficerMap.getOrDefault(bc.getOfficer(), null))
                            .map(bho -> new Officer(bho.getName(), bho.getIdType(), bho.getId().toString(), bho.getTel(), bho.getMobile(), bho.getEmail()))
                            .orElse(null),
                        bc.getAddress(),
                        bc.getZipCode(),
                        bc.getRegisterTime()
                    )
                );
                if (USER_TYPE_INTERNET.equals(bc.getUserType())) {
                    userInfo.getInfo()
                        .setServiceInfo(serviceInfo);
                } else {
                    userInfo
                        .getInfo()
                        .setHouseHoldInfo(
                            houseHoldInfoList
                        )
                        .setServiceRegTime(bc.getServiceRegTime());
                }
                return userInfo;
            })
            .collect(Collectors.toList());
    }

    /**
     * 根据占用机房获取机房 id
     */
    private Long getHouseIdByBaseHousesHoldInfo(List<BaseIdcHouseArea> baseIdcHouseAreaList, List<BaseFrameInfo> baseFrameInfoList, BaseHousesHoldInfo bhhi) {
        return baseFrameInfoList.stream()
            .filter(bfi -> bfi.getId().equals(bhhi.getFrameInfoId()))
            .findFirst()
            .map(baseFrameInfo -> baseIdcHouseAreaList.stream()
                .filter(biha -> biha.getId().equals(baseFrameInfo.getHouseArea()))
                .findFirst()
                .map(BaseIdcHouseArea::getHouseId)
                .orElse(null)
            )
            .orElse(null);
    }
}
